/**
 * Foxit Software Inc.
 * Copyright(C) 2005-2014, all rights reserved.
 * The following code is copyrighted and contains proprietary information
 * and trade secrets of Foxit Software Inc.

 * Description: MarkupAnnotHandler
 * Author: shaojie zhuo
 * Update: shaojie zhuo (2014-05-28 11:23)
 */

define(function (require, exports, module) {
    require("./PopupMousePtHandler.js");
    var PDFRect = WebPDF.PDFRect;
    var RectUtils = WebPDF.RectUtils;
    var ROPE_SHAPE_FACTOR1 = 0.95;
    var ROPE_SHAPE_FACTOR2 = 0.05;
    var ROPE_PI = 3.141592653;
    var ROPE_THICKNESS = 28;
    WebPDF.MarkupAnnotHandler = function(readerApp, annotHandlerManager){
        var _readerApp = readerApp,
            _annotHandlerManager = annotHandlerManager,
            _annotUIManager = _annotHandlerManager.getUIManager(),
            _self = this;
        var _focusPopupAnnotInfo = { pageIndex: -1, annotName: null, isFocus: false };
        var _curVisibleRope =  { pageIndex: -1, annotName: null };

        this.init = function(){
            var popupMousePtHandler = new WebPDF.Event.PopupMousePtHandler(_self, _annotHandlerManager);
            _readerApp.registerMousePtHandler(popupMousePtHandler);

            $(_readerApp).on(WebPDF.EventList.DOCVIEW_SCROLL,function(){
                _onDocViewScroll();
            });

            var $mainFrame = $('#' + _readerApp.getAppId());

            $mainFrame.on('click', '.fwr_popup_content[contenteditable]',function(event){
                var target = _self.getDirectPopupParent(event.target);
                if(target){
                    _self.setFocusAnnotByTarget(target,false);
                }
                //这里停止冒泡，这样不会对popup进行拖动
                event.stopPropagation();
                return false;
            });
            $mainFrame.on('mousedown touchstart', '.fwr-annot-close-btn', function (event) {
                try {
                    if (event.button != 0 && event.button != 1) {
                        return true;
                    }
                    var pageIndex = parseInt(event.target.parentNode.parentNode.getAttribute("page-index"));
                    var annotName = event.target.parentNode.parentNode.getAttribute("annot-name");
                    var pageView = _readerApp.getMainView().getDocView().getPageView(pageIndex);
                    _hidePopupAnnot(pageView, annotName);
                    return true;
                }
                catch (ex) {
                    console.error(ex);
                    return false;
                }
            });

            $mainFrame.on('mouseenter mouseleave', '.fwr-popup-annot', function (event) {
                //jquery 1.4.1 mouseenter mouseleave
                //jquery 1.4.2 mouseover mouseout
                //高于jquery1.4.2 mouseover mouseenter;
                if (event.type == 'mouseover' || event.type == 'mouseenter') {
                    try {
                        var pageIndex = parseInt(event.currentTarget.getAttribute("page-index"));
                        var annotName = event.currentTarget.getAttribute("annot-name");
                        var pageView = _readerApp.getMainView().getDocView().getPageView(pageIndex);
                        var pdfPage = pageView.getPDFPage();
                        var annot = pdfPage.getAnnotByName(annotName);
                        _self.onMouseOver(pageView, annot, event);
                        return false;
                    }
                    catch (ex) {
                        console.error(ex);
                        return false;
                    }
                }
                else if (event.type == 'mouseout' || event.type == 'mouseleave') {
                    try {
                        _curVisibleRope.pageIndex = -1;
                        _curVisibleRope.annotName = null;
                        _annotHandlerManager.onDraw();
                        return true;
                    }
                    catch (ex) {
                        console.error(ex);
                        return false;
                    }
                }
            });

            $mainFrame.on('focus', '.fwr_popup_content', function () {
                var $this = $(this);
                if (!_readerApp.isEditable()) {
                    $this.attr('contenteditable', 'false');
                    return;
                }
                else
                    $this.attr('contenteditable', 'true');
                if (typeof $this.get(0).innerText != 'undefined')
                    $this.data('before', $this.get(0).innerText);
                else
                    $this.data('before', $this.get(0).textContent);
                return true;
            }).on('blur keyup paste', '.fwr_popup_content', function (event) {
                if (event.type == 'blur') {
                    $(this).parents(".fwr-popup-annot").removeClass("fwr-popup-annot-focus");
                }

                var $this = $(this);
                if (!_readerApp.isEditable()) {
                    return false;
                }
                else
                    $this.attr('contenteditable', 'true');
                var text = null;
                if (typeof $this.get(0).innerText != 'undefined')
                    text = $this.get(0).innerText;
                else
                    text = $this.get(0).textContent;
                var oldText = $this.data('before');
                if (typeof oldText == "undefined" || oldText == null) {
                    oldText = text;
                    $this.data('before', text);
                }
                if (oldText != text) {
                    $this.data('before', text);
                    var jqParentAnnot = $this.closest(".fwr-popup-annot");
                    var pageIndex = parseInt(jqParentAnnot.attr("page-index"));
                    var parentAnnotName = jqParentAnnot.attr("annot-name");
                    var docView = _readerApp.getMainView().getDocView();
                    var pageView = docView.getPageView(pageIndex);
                    var pdfPage = pageView.getPDFPage();
                    var annot = pdfPage.getAnnotByName(parentAnnotName);
                    if (annot == null)
                        return;
                    var replyValue = $this.attr("annot-reply");
                    var isReply = (replyValue == "true");
                    var timestamp = (new Date()).valueOf().toString();
                    if (isReply) {
                        var replyAnnotName = $this.attr("annot-name");
                        var replyAnnot = annot.getReplyAnnotByName(replyAnnotName);
                        if (replyAnnot == null)
                            return;
                        replyAnnot.setContents(text);
                        replyAnnot.setModifyDate(timestamp);
                    }
                    else {
                        annot.setContents(text);
                    }

                    annot.setModifyDate(timestamp);
                    _readerApp.setModified(pageView, docView, true);
                }
                return true;
            });

        };

        function _onDocViewScroll(){
            var docView = _readerApp.getMainView().getDocView();
            var visiblePageRange = docView.getVisiblePageRange();
            var jqPagesContainerDiv = $("#" + docView.getDocViewContainerID());
            var docViewDimension = docView.getDocViewDimension();
            var contentPanelHeight = docViewDimension.height;
            var contentPanelWidth = docViewDimension.width;
            var contentPanelOffset = jqPagesContainerDiv.offset();
            var annotVisibleRect, pageView;
            for (var i = visiblePageRange.begin; i <= visiblePageRange.end; i++) {
                pageView = docView.getPageView(i);
                annotVisibleRect = _annotHandlerManager.getAnnotVisibleRect(pageView, contentPanelOffset,
                    contentPanelWidth, contentPanelHeight);
                pageView.getPDFPage().enumAnnots(function (annot) {
                    if(annot.getType() === WebPDF.PDFData.AnnotType.MarkUp){
                        _updatePopupPosition(pageView,annotVisibleRect,annot);
                    }
                });
            }
        }

        this.getDirectPopupParent = function(node) {
            var tmpNode = node;
            var regex_popup_annot = new RegExp("(^|\\s)" + "fwr-popup-annot" + "(\\s|$)");
            while (tmpNode != null && !regex_popup_annot.test(tmpNode.className)) {

                tmpNode = tmpNode.parentNode;
                if (/^body|html$/i.test(tmpNode.nodeName)) {
                    // we ended up too high in the document structure. Quit!
                    return null;
                }
            }
            return tmpNode;
        };

        this.setFocusAnnotByTarget = function(popupElem,isFocusContent) {
            var pageIndex = parseInt(popupElem.getAttribute("page-index"));
            var annotName = popupElem.getAttribute("annot-name");
            if(typeof isFocusContent=="undefined" || isFocusContent==null || isFocusContent==true)
                isFocusContent = true;
            _setPopupFocus(readerApp.getMainView().getDocView().getPageView(pageIndex),annotName,isFocusContent);
        };

        function _bringPopupToFrontEnd(pageView, annotName) {          
            if (_focusPopupAnnotInfo.annotName != null && _focusPopupAnnotInfo.page != -1) {
                var oldPageView = pageView.getDocView().getPageView(_focusPopupAnnotInfo.pageIndex);
                var jqPopup = $("#" + _annotUIManager.getAnnotPopupDivID(oldPageView, _focusPopupAnnotInfo.annotName));
                if (jqPopup != null) {
                    jqPopup.removeClass("fwr-popup-annot-focus fwr-popup-annot-to-frontend");
                }
            }
            _focusPopupAnnotInfo.annotName = annotName;
            _focusPopupAnnotInfo.page = pageView.getPageIndex();
            var popupDivID = _annotUIManager.getAnnotPopupDivID(pageView, annotName);
            var jqNewPopup = $("#" + popupDivID);
            jqNewPopup.addClass("fwr-popup-annot-to-frontend");
            
            _setPopupFocus(pageView, annotName, true)
        }

        function _setVisibleRope(pageIndex, annotName) {
            _curVisibleRope.pageIndex = pageIndex;
            _curVisibleRope.annotName = annotName;
        }

        function _placeCaretAtEnd(el) {
            if (typeof window.getSelection != "undefined"
                && typeof document.createRange != "undefined") {
                var range = document.createRange();
                range.selectNodeContents(el);
                range.collapse(false);
                var sel = window.getSelection();
                sel.removeAllRanges();
                sel.addRange(range);
                el.focus();
            } else if (typeof document.body.createTextRange != "undefined") {
                var textRange = document.body.createTextRange();
                textRange.moveToElementText(el);
                textRange.collapse(false);
                textRange.select();
            }
        }

        function _setPopupFocus(pageView, annotName, isFocusContent) {
            var pageIndex = pageView.getPageIndex();
            var popupDivID = _annotUIManager.getAnnotPopupDivID(pageView, annotName);
            var jqNewPopup = $("#" + popupDivID);
            if (annotName != _focusPopupAnnotInfo.annotName || _focusPopupAnnotInfo.pageIndex != pageIndex) {
                if (_focusPopupAnnotInfo.annotName != null && _focusPopupAnnotInfo.pageIndex != -1) {
                    var oldPageView = pageView.getDocView().getPageView(_focusPopupAnnotInfo.pageIndex);
                    var jqPopup = $("#" + _annotUIManager.getAnnotPopupDivID(oldPageView, _focusPopupAnnotInfo.annotName));
                    if (jqPopup != null) {
                        jqPopup.removeClass("fwr-popup-annot-to-frontend");
                        jqPopup.removeClass("fwr-popup-annot-focus");
                    }
                }
                if (isFocusContent != false)
                    isFocusContent = true;
            }
            if(_readerApp.isEditable()){
                if (!_focusPopupAnnotInfo.isFocus && isFocusContent != false) {
                    isFocusContent = true;
                }
                if (isFocusContent) {
                    var jqContent = $("#" + popupDivID + " .fwr_popup_content:first-child");
                    if (jqContent.length > 0) {
                        _placeCaretAtEnd(jqContent.get(0));
                    }
                }
            }
            jqNewPopup.addClass("fwr-popup-annot-focus");
            _focusPopupAnnotInfo.annotName = annotName;
            _focusPopupAnnotInfo.pageIndex = pageIndex;
            _focusPopupAnnotInfo.isFocus = true;
        }

        function _bindPopupContextmenuEvent () {
            $(".fwr-popup-annot").off("contextmenu", _popupContextMenuHandler).on("contextmenu", _popupContextMenuHandler);
        }

        function _popupContextMenuHandler (event) {
            if (_readerApp.isEditable()) {
                var pageIndex = parseInt(event.currentTarget.getAttribute("page-index"));
                var annotName = event.currentTarget.getAttribute("annot-name");
                var pageView = _readerApp.getMainView().getDocView().getPageView(pageIndex);
                var pdfPage = pageView.getPDFPage();
                var annot = pdfPage.getAnnotByName(annotName);
                if (annot != null) {
                    var annotHandler = _annotHandlerManager.canAnswer(annot, true);
                    if (annotHandler == null) {
                        return true;
                    }
                    _annotHandlerManager.clickOnAnnot(annot, pageView, false);
                    $(".fwr-annot_selected").trigger("contextmenu.fwrContextMenu", event);
                    return false;
                }
            }
            return true;
        }

        function _drawAnnotRope (canvas2DContext, canvasOffset, annotName, pageIndex) {
            var docView = _readerApp.getMainView().getDocView();
            var pageView = docView.getPageView(pageIndex);
            if (!pageView)
                return false;
            var pdfPage = pageView.getPDFPage();
            var annot = pdfPage.getAnnotByName(annotName);
            if (!annot)
                return false;
            if (annot.getType() != WebPDF.PDFData.AnnotType.MarkUp)
                return false;
            var popup = annot.getPopup();
            if (popup == null)
                return false;
            if (popup.getOpenState() == 0)
                return false;
            var pageOffset = $("#" + pageView.getPageViewContainerID()).offset();//pageView.getPageViewDivOffset();
            if (pageOffset == null)
                return false;
            pageOffset.left -= canvasOffset.left;
            pageOffset.top -= canvasOffset.top;
            var annotDivID = _annotUIManager.getAnnotDivID(pageView, annotName);
            var jqAnnot = $("#" + annotDivID);
            var popupDivID = _annotUIManager.getAnnotPopupDivID(pageView, annotName);
            var jqPopup = $("#" + popupDivID);
            var annotPosition = jqAnnot.position();
            var popupPosition = jqPopup.position();
            if (annotPosition == null || popupPosition == null)
                return false;
            var annotRect = new PDFRect(annotPosition.left, annotPosition.top, jqAnnot.width() + annotPosition.left,
                    jqAnnot.height() + annotPosition.top);
            var popupRect = new PDFRect(popupPosition.left, popupPosition.top, jqPopup.width() + popupPosition.left,
                    jqPopup.height() + popupPosition.top);
            RectUtils.offset(annotRect, pageOffset.left, pageOffset.top);
            RectUtils.offset(popupRect, pageOffset.left, pageOffset.top);

            var rcShipCaption = new PDFRect(popupRect.left, popupRect.top, popupRect.right, popupRect.top + 20);
            if (rcShipCaption.bottom > popupRect.bottom)
                rcShipCaption.bottom = popupRect.bottom;
            var tmpRect = new PDFRect(0, 0, 0, 0);
            RectUtils.copy(popupRect, tmpRect);
            RectUtils.normalize(tmpRect);
            var ptAnchor = new WebPDF.PDFPoint((annotRect.left + annotRect.right) / 2, (annotRect.top + annotRect.bottom) / 2);
            if (RectUtils.ptInRect(tmpRect, ptAnchor))
                return false;

            var dbAngleFirst = ROPE_PI * 2.0;
            var dbAngleSecond = ROPE_PI * 2.0;
            var rcFirst = new PDFRect(0, 0, 0, 0), rcSecond = new PDFRect(0, 0, 0, 0), rcNew = new PDFRect(0, 0, 0, 0);
            var ptFirst = new WebPDF.PDFPoint(0, 0), ptSecond = new WebPDF.PDFPoint(0, 0);
            if (ptAnchor.x < popupRect.left) {
                rcFirst.left = ptAnchor.x;
                rcFirst.right = popupRect.left;
                rcFirst.top = Math.min(ptAnchor.y, popupRect.top);
                rcFirst.bottom = Math.max(ptAnchor.y, popupRect.bottom);
                dbAngleFirst = Math.atan2((rcShipCaption.top + rcShipCaption.bottom) / 2.0 - ptAnchor.y, RectUtils.width(rcFirst));
            }
            else if (ptAnchor.x > popupRect.right) {
                rcFirst.left = popupRect.right;
                rcFirst.right = ptAnchor.x;
                rcFirst.top = Math.min(ptAnchor.y, popupRect.top);
                rcFirst.bottom = Math.max(ptAnchor.y, popupRect.bottom);
                dbAngleFirst = Math.atan2((rcShipCaption.top + rcShipCaption.bottom) / 2.0 - ptAnchor.y, RectUtils.width(rcFirst));
            }

            if (ptAnchor.y < popupRect.top) {
                rcSecond.left = Math.min(ptAnchor.x, popupRect.left);
                rcSecond.right = Math.max(ptAnchor.x, popupRect.right);
                rcSecond.top = ptAnchor.y;
                rcSecond.bottom = popupRect.top;
                dbAngleSecond = Math.atan2((popupRect.left + popupRect.right) / 2.0 - ptAnchor.x, RectUtils.height(rcSecond));
            }
            else if (ptAnchor.y > popupRect.bottom) {
                rcSecond.left = Math.min(ptAnchor.x, popupRect.left);
                rcSecond.right = Math.max(ptAnchor.x, popupRect.right);
                rcSecond.top = popupRect.bottom;
                rcSecond.bottom = ptAnchor.y;
                dbAngleSecond = Math.atan2((popupRect.left + popupRect.right) / 2.0 - ptAnchor.x, RectUtils.height(rcSecond));
            }

            if (Math.abs(dbAngleFirst) < Math.abs(dbAngleSecond)) {
                RectUtils.copy(rcFirst, rcNew);
                if (ptAnchor.x < popupRect.left) {
                    ptFirst.x = popupRect.left;
                    ptSecond.x = popupRect.left;
                }
                else {
                    ptFirst.x = popupRect.right;
                    ptSecond.x = popupRect.right;
                }

                var y = (rcShipCaption.top + rcShipCaption.bottom) / 2;
                var yStep = (ROPE_THICKNESS / (Math.cos(dbAngleFirst) * 2) + 0.5);

                ptFirst.y = y - yStep;
                ptSecond.y = y + yStep;

                ptFirst.y = Math.max(ptFirst.y, popupRect.top);
                ptFirst.y = Math.min(ptFirst.y, popupRect.bottom);
                ptSecond.y = Math.max(ptSecond.y, popupRect.top);
                ptSecond.y = Math.min(ptSecond.y, popupRect.bottom);
            }
            else {
                RectUtils.copy(rcSecond, rcNew);
                if (ptAnchor.y < popupRect.top) {
                    ptFirst.y = popupRect.top;
                    ptSecond.y = popupRect.top;
                }
                else {
                    ptFirst.y = popupRect.bottom;
                    ptSecond.y = popupRect.bottom;
                }

                var x = (popupRect.left + popupRect.right) / 2;
                var xStep = (ROPE_THICKNESS / (Math.cos(dbAngleSecond) * 2) + 0.5);

                ptFirst.x = x - xStep;
                ptSecond.x = x + xStep;

                ptFirst.x = Math.max(ptFirst.x, popupRect.left);
                ptFirst.x = Math.min(ptFirst.x, popupRect.right);
                ptSecond.x = Math.max(ptSecond.x, popupRect.left);
                ptSecond.x = Math.min(ptSecond.x, popupRect.right);
            }
            var annotColor = annot.getColor();
            _drawRope(canvas2DContext, ptAnchor.x, ptAnchor.y, ptFirst.x, ptFirst.y, ptSecond.x, ptSecond.y,
                "rgba(125,125,125,0.35)", "rgba(125,125,125,0.35)", 2.0);
            _drawRope(canvas2DContext, ptAnchor.x, ptAnchor.y, ptFirst.x, ptFirst.y, ptSecond.x, ptSecond.y,
                WebPDF.Common.hexColor2Rgba(annotColor, 0.7), WebPDF.Common.hexColor2Rgba(annotColor, 1), 1.0);
            return true;
        }

        function _drawRope(ctx, pt1_x, pt1_y, pt2_x, pt2_y, pt3_x, pt3_y, crFill, crStroke, nLineWidth) {
            if (ctx == null)
                return;
            ctx.save();
            var ptCenter_x = (pt1_x + pt2_x + pt3_x) / 3;
            var ptCenter_y = (pt1_y + pt2_y + pt3_y) / 3;
            ctx.beginPath();
            ctx.moveTo(pt1_x, pt1_y);
            var controlPt1_x = pt1_x + (ptCenter_x - pt1_x) * ROPE_SHAPE_FACTOR2;
            var controlPt1_y = pt1_y + (ptCenter_y - pt1_y) * ROPE_SHAPE_FACTOR2;

            var controlPt2_x = pt2_x + (ptCenter_x - pt2_x) * ROPE_SHAPE_FACTOR1;
            var controlPt2_y = pt2_y + (ptCenter_y - pt2_y) * ROPE_SHAPE_FACTOR1;
            ctx.bezierCurveTo(controlPt1_x, controlPt1_y, controlPt2_x, controlPt2_y, pt2_x, pt2_y);
            ctx.lineTo(pt3_x, pt3_y);

            var controlPt3_x = pt3_x + (ptCenter_x - pt3_x) * ROPE_SHAPE_FACTOR1;
            var controlPt3_y = pt3_y + (ptCenter_y - pt3_y) * ROPE_SHAPE_FACTOR1;
            var controlPt4_x = pt1_x + (ptCenter_x - pt1_x) * ROPE_SHAPE_FACTOR2;
            var controlPt4_y = pt1_y + (ptCenter_y - pt1_y) * ROPE_SHAPE_FACTOR2;
            ctx.bezierCurveTo(controlPt3_x, controlPt3_y, controlPt4_x, controlPt4_y, pt1_x, pt1_y);

            ctx.closePath();
            ctx.fillStyle = crFill;
            ctx.fill();
            ctx.strokeStyle = crStroke;
            ctx.lineWidth = nLineWidth;
            ctx.stroke();

            ctx.restore();
        }

        function _updatePopupPosition (pageView, visibleRect, annot) {
            var popup = annot.getPopup();
            if (popup == null)
                return;
            var visibleReaderClone = WebPDF.Common.clone(visibleRect);
            WebPDF.RectUtils.deflate(visibleReaderClone, 1);
            var popupDivID = _annotUIManager.getAnnotPopupDivID(pageView, annot.getAnnotName());
            var jqPopup = $("#" + popupDivID);
            var popupPDFRect = popup.getRect();
            var popupDocRect = pageView.pdfToDoc(popupPDFRect, false);
            var width = jqPopup.outerWidth();
            var height = jqPopup.outerHeight();
            var pageViewHeight = pageView.getPageViewHeight();
            if (popupDocRect.top < visibleReaderClone.top) {
                popupDocRect.top = visibleReaderClone.top;
                popupDocRect.bottom = popupDocRect.top + height;
                popupDocRect.bottom = Math.min(pageViewHeight, popupDocRect.top + height);
                popupDocRect.top = Math.max(0, popupDocRect.bottom - height);
            } else if (popupDocRect.bottom > visibleReaderClone.bottom) {
                popupDocRect.bottom = visibleReaderClone.bottom;
                popupDocRect.top = Math.max(0, popupDocRect.bottom - height);
                popupDocRect.bottom = Math.min(pageViewHeight, popupDocRect.top + height);
            }

            if (popupDocRect.left < visibleReaderClone.left) {
                popupDocRect.left = visibleReaderClone.left;
                popupDocRect.right = popupDocRect.left + width;
            }
            if (popupDocRect.right > visibleReaderClone.right) {
                popupDocRect.right = visibleReaderClone.right;
                if (popupDocRect.right - width > visibleReaderClone.left)
                    popupDocRect.left = popupDocRect.right - width;
                if (popupDocRect.left >= popupDocRect.right)
                    popupDocRect.left = popupDocRect.right - width;
                if (popupDocRect.left < visibleReaderClone.left)
                    popupDocRect.left = visibleReaderClone.left;
            }

            $("#" + popupDivID).css({
                left: popupDocRect.left,
                top: popupDocRect.top
            });
        }

        this.moveCurrentPopupAnnot = function(offsetX, offsetY){
            _self.movePopupAnnot(_focusPopupAnnotInfo.pageIndex, _focusPopupAnnotInfo.annotName,offsetX,offsetY);
        };

        this.movePopupAnnot = function (pageIndex, annotName, offsetX, offsetY) {
            var docView = _readerApp.getMainView().getDocView();
            var pageView = docView.getPageView(pageIndex);
            if (!pageView)
                return false;
            var pdfPage = pageView.getPDFPage();
            var annot = pdfPage.getAnnotByName(annotName);
            if (!annot)
                return false;
            if (annot.getType() != WebPDF.PDFData.AnnotType.MarkUp)
                return false;
            var popup = annot.getPopup();
            if (popup == null)
                return false;

            var popupDivID = _annotUIManager.getAnnotPopupDivID(pageView, annot.getAnnotName());
            var popupOldPDFRect = popup.getRect();
            var popupOldDocRect = pageView.pdfToDoc(popupOldPDFRect, false);
            var jqPopup = $("#" + popupDivID);
            var jqOldPosition = jqPopup.position();
            var oldPopupLeft = jqOldPosition.left;
            var oldPopupTop = jqOldPosition.top;
            var offsetXForAdjust = oldPopupLeft - popupOldDocRect.left;
            var offsetYForAdjust = oldPopupTop - popupOldDocRect.top;
            var deviation = 1;
            if (offsetYForAdjust > deviation) //Popup经过调整往下移了
            {
                if (offsetY <= 0)
                    offsetY = 0;
                else
                    offsetY += offsetYForAdjust;
            }
            else if (offsetYForAdjust < -deviation) {
                if (offsetY >= 0)
                    offsetY = 0;
                else
                    offsetY += offsetYForAdjust;
            }
            if (offsetXForAdjust > deviation) //Popup经过调整往右移了
            {
                if (offsetX <= 0)
                    offsetX = 0;
                else
                    offsetX += offsetXForAdjust;
            }
            else if (offsetXForAdjust < -deviation) {
                if (offsetX >= 0)
                    offsetX = 0;
                else
                    offsetX += offsetXForAdjust;
            }

            var popupPDFRect = popup.getRect();
            var nPt2Pixel = _readerApp.getPixelsPerPoint();
            RectUtils.offset(popupPDFRect, offsetX / pageView.getScale() / nPt2Pixel, -offsetY / pageView.getScale() / nPt2Pixel);
            popup.setRect(popupPDFRect);
            var jqPagesContainerDiv = $("#" + docView.getDocViewContainerID());
            var docViewDimension = docView.getDocViewDimension();
            var contentPanelHeight = docViewDimension.height;
            var contentPanelWidth = docViewDimension.width;
            var contentPanelOffset = jqPagesContainerDiv.offset();
            var annotVisibleRect = _annotHandlerManager.getAnnotVisibleRect(pageView, contentPanelOffset,
                contentPanelWidth, contentPanelHeight);
            _updatePopupPosition (pageView, annotVisibleRect, annot);
            _readerApp.setModified(pageView, docView, true);
        };

        function _hidePopupAnnot (pageView, annotName) {
            var pdfPage = pageView.getPDFPage();
            var annot = pdfPage.getAnnotByName(annotName);
            if (annot == null)
                return;
            var popup = annot.getPopup();
            if (popup == null)
                return;
            var id = _annotUIManager.getAnnotPopupDivID(pageView, annotName);
            var jqPopup = $("#" + id);
            if (jqPopup == null)
                return;
            jqPopup.hide();
            popup.setOpenState(0);
        }

        function _changePopupAnnotState (pageView, annotName) {
            var pdfPage = pageView.getPDFPage();
            var annot = pdfPage.getAnnotByName(annotName);
            if (annot == null) {
                return 0;
            }
            if (annot.getType() != WebPDF.PDFData.AnnotType.MarkUp) {
                return 0;
            }
            var popup = annot.getPopup();
            if (popup == null) {
                var dt = new Date();
                var time = dt.valueOf() + dt.getTimezoneOffset() * 60000;
                var timestamp = (Math.floor(time / 1000)).toString();
                var annotRect = annot.getRect();
                var popupRect = new WebPDF.PDFRect(0, 0, 0, 0);
                popupRect.top = annotRect.top;
                popupRect.right = pdfPage.getPageWidth();
                popupRect.left = popupRect.right - WebPDF.PDFData.MKA_POPUPWIDTH;
                popupRect.bottom = popupRect.top - WebPDF.PDFData.MKA_POPUPHEIGHT;
                var jsonPopup =
                {
                    f: WebPDF.PDFData.AnnotFlag.ANNOTFLAG_PRINT,
                    md: timestamp,
                    n: timestamp + "_popup",
                    op: 0,
                    rc: [popupRect.left, popupRect.top, popupRect.right, popupRect.bottom]
                };
                annot.setPopupData(jsonPopup);
                var popupDivHtml = _annotUIManager.createPopupAnnotHtmlContent(annot, pageView);
                var annotsDivID = _annotUIManager.getPageAnnotsContainerID(pageView);
                $("#" + annotsDivID).append(popupDivHtml);
                popup = annot.getPopup();
            }
            if (popup == null) {
                return 0;
            }
            var id = _annotUIManager.getAnnotPopupDivID(pageView, annotName);
            var jqPopup = $("#" + id);
            if (jqPopup == null)
                return 0;
            if (popup.getOpenState() === 0) {
                jqPopup.show();
                var jqPagesContainerDiv = $("#" + pageView.getDocView().getDocViewContainerID());
                var docViewDimension = pageView.getDocView().getDocViewDimension();
                var contentPanelHeight = docViewDimension.height;
                var contentPanelWidth = docViewDimension.width;
                var contentPanelOffset = jqPagesContainerDiv.offset();
                var annotVisibleRect = _annotHandlerManager.getAnnotVisibleRect(pageView, contentPanelOffset, contentPanelWidth,
                    contentPanelHeight);
                _updatePopupPosition(pageView, annotVisibleRect, annot);
                popup.setOpenState(1);
                return 1;
            }
            else {
                jqPopup.hide();
                popup.setOpenState(0);
                return 0;
            }
        }

        this.onDraw = function(canvas2DContext, canvasPosition){
            if (_curVisibleRope.pageIndex != -1 && _curVisibleRope.annotName != null) {
                _drawAnnotRope(canvas2DContext, canvasPosition, _curVisibleRope.annotName, _curVisibleRope.pageIndex);
            }
        };

        this.onFocus = function (pageView, annot) {
            var popupAnnot = annot.getPopup();
            if (popupAnnot && popupAnnot.getOpenState() === 1) {
                _bringPopupToFrontEnd(pageView, annot.getAnnotName(), _annotUIManager);
            }
        };

        this.onLButtonDblClk = function (pageView, annot) {
            _setVisibleRope(-1, null);
            var ancestorAnnot = annot.getHeadAncestorAnnot();
            var focusAnnot = ancestorAnnot ? ancestorAnnot : annot;
            var annotName = focusAnnot.getAnnotName();
            if (_changePopupAnnotState(pageView, annotName) == 1) {
                _setVisibleRope(pageView.getPageIndex(), annotName);
                _setPopupFocus(pageView, annotName, true);
            }
            _readerApp.setModified(pageView, pageView.getDocView(), true);
            _annotHandlerManager.onDraw();
        };

        this.onMouseOver = function (pageView, annot, event) {
            var annotName = annot.getAnnotName();
            var pageIndex = pageView.getPageIndex();
            _curVisibleRope.pageIndex = pageIndex;
            _curVisibleRope.annotName = annotName;
            var ancestorAnnot = annot.getHeadAncestorAnnot();
            if (ancestorAnnot != null) {
                _curVisibleRope.pageIndex = pageIndex;
                _curVisibleRope.annotName = ancestorAnnot.getAnnotName();
            }
            else {
                _curVisibleRope.pageIndex = pageIndex;
                _curVisibleRope.annotName = annotName;
            }
            _annotHandlerManager.onDraw();
            return true;
        };

        this.onMouseLeave = function (pageView, annot, event) {
            _curVisibleRope.pageIndex = -1;
            _curVisibleRope.annotName = null;
            _annotHandlerManager.onDraw();
            return true;
        };

        this.onUpdatePosition = function(pageView, annot, visibleRect){

        };
    };

    return WebPDF.MarkupAnnotHandler;
});